package com.fy.fyai.common.utils;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.COSObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 腾讯云 COS 文件下载工具类（仅需传递完整COS路径）
 */
@Component
public class CosFullPathDownloadUtil {

    @Autowired
    private COSClient cosClient;

    // 本地默认下载目录（可配置在 application.yml，这里直接指定 E 盘目录）
    private String localDefaultDir = "F:/COS下载文件/";

    // 正则表达式：解析 COS 完整路径（格式：https://{bucket}.cos.{region}.myqcloud.com/{fileKey}）
    private static final Pattern COS_FULL_PATH_PATTERN = Pattern.compile(
        "https?://([^.]+)\\.cos\\.([^.]+)\\.myqcloud\\.com/(.*)"
    );

    /**
     * 核心方法：传递 COS 完整文件路径，下载到本地指定目录
     * @param fileId 文件ID（例如：1G_file.zip）
     * @throws Exception 解析路径失败、下载失败、文件写入失败等异常
     */
    public void downloadFromCos(String fileId) throws Exception {

        String filePath = "https://fy-1330848370.cos.ap-guangzhou.myqcloud.com/20250817_162655.mp4";
        // 1. 解析 COS 完整路径，提取 bucket、region、fileKey
        PathParseResult parseResult = parseCosFullPath(filePath);
        String bucketName = parseResult.bucket;
        String region = parseResult.region;
        String fileKey = parseResult.fileKey;

        // 2. 构建本地保存路径（默认目录 + 原文件名称，避免文件名冲突）
        String fileName = extractFileName(fileKey);
        String localSavePath = buildLocalSavePath(localDefaultDir, fileName);

        // 3. 流式下载并写入本地
        downloadToLocal(bucketName, fileKey, localSavePath);
    }

    /**
     * 解析 COS 完整路径，提取 bucket、region、fileKey
     */
    private PathParseResult parseCosFullPath(String cosFullPath) throws Exception {
        Matcher matcher = COS_FULL_PATH_PATTERN.matcher(cosFullPath);
        if (!matcher.matches()) {
            throw new IllegalArgumentException("COS 完整路径格式错误：" + cosFullPath + 
                "，正确格式：https://{bucket}.cos.{region}.myqcloud.com/{fileKey}");
        }
        // 分组说明：1->bucket，2->region，3->fileKey
        String bucket = matcher.group(1);
        String region = matcher.group(2);
        String fileKey = matcher.group(3);

        // 校验必填项
        if (bucket == null || region == null || fileKey == null || fileKey.isEmpty()) {
            throw new Exception("解析 COS 路径失败，缺少关键信息：" + cosFullPath);
        }
        return new PathParseResult(bucket, region, fileKey);
    }

    /**
     * 从 fileKey 中提取文件名（例如：test/abc/123.zip -> 123.zip）
     */
    private String extractFileName(String fileKey) {
        int lastSlashIndex = fileKey.lastIndexOf("/");
        return lastSlashIndex == -1 ? fileKey : fileKey.substring(lastSlashIndex + 1);
    }

    /**
     * 构建本地保存路径（创建目录，处理文件名冲突）
     */
    private String buildLocalSavePath(String localDir, String fileName) throws IOException {
        // 创建本地目录（不存在则创建）
        File dir = new File(localDir);
        if (!dir.exists()) {
            boolean mkdirsSuccess = dir.mkdirs();
            if (!mkdirsSuccess) {
                throw new IOException("创建本地下载目录失败：" + localDir);
            }
        }

        // 处理文件名冲突（例如：123.zip 已存在 -> 123_1.zip）
        String localPath = localDir + File.separator + fileName;
        File localFile = new File(localPath);
        int suffix = 1;
        while (localFile.exists()) {
            String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) 
                + "_" + suffix + fileName.substring(fileName.lastIndexOf("."));
            localPath = localDir + File.separator + newFileName;
            localFile = new File(localPath);
            suffix++;
        }
        return localPath;
    }

    /**
     * 流式下载 COS 文件到本地
     */
    private void downloadToLocal(String bucketName, String fileKey, String localSavePath) throws IOException {
        GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, fileKey);

        try (COSObject cosObject = cosClient.getObject(getObjectRequest);
             InputStream cosIn = cosObject.getObjectContent();
             BufferedOutputStream localOut = new BufferedOutputStream(new FileOutputStream(localSavePath))) {

            byte[] buffer = new byte[8192]; // 8KB 缓冲区，优化 IO
            int bytesRead;
            while ((bytesRead = cosIn.read(buffer)) != -1) {
                localOut.write(buffer, 0, bytesRead);
            }
            localOut.flush();
            System.out.println("文件下载完成！本地保存路径：" + localSavePath);

        } catch (Exception e) {
            // 下载失败，删除不完整文件
            new File(localSavePath).delete();
            throw new IOException("COS 文件下载失败：bucket=" + bucketName + ", fileKey=" + fileKey, e);
        }
    }

    /**
     * 内部静态类：存储路径解析结果
     */
    private static class PathParseResult {
        String bucket;
        String region;
        String fileKey;

        public PathParseResult(String bucket, String region, String fileKey) {
            this.bucket = bucket;
            this.region = region;
            this.fileKey = fileKey;
        }
    }
}